home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1997 February: Technology Seed / Mac Tech Seed Feb '97.toast / OpenDoc 1.2b2c1 / Implementation / Dialogs / AGSupprt.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1997-02-13  |  15.0 KB  |  611 lines  |  [TEXT/MPS ]

  1. /*
  2.     File:        AGSupprt.cpp
  3.  
  4.     Contains:    xxx put contents here xxx
  5.  
  6.     Owned by:    Yan Arrouye
  7.  
  8.     Copyright:    © 1995-1996 by Apple Computer, Inc., all rights reserved.
  9.  
  10.     Change History (most recent first):
  11.  
  12.          <6>     9/16/96    eeh        1386008: back to Gestalt on 68K
  13.          <5>     9/12/96    eeh        1386008: weak link against appleguidelib
  14.          <4>     9/11/96    eeh        1386008: AG fix for 68K
  15.          <3>     9/10/96    eeh        1386008: AppleGuide support (incomplete)
  16.          <2>      7/8/96    eeh        undo task 10008 (AppleGuide buttons)
  17.          <7>     5/16/96    Yan        Style check
  18.          <6>     5/09/96    Yan        Fixed leak
  19.          <5>     5/08/96    Yan        fixed momory leaks
  20.          <4>     4/25/96    Yan        Use CopyPascalString instead of BlockMoveData
  21.          <3>     2/20/96    tb        Placed #if qDebug around TraceMonitor support.
  22.          <2>    10/26/95    Yan        • Added support for CodeWarrior. Requires that you rename the
  23.                                     AppleGuideGlue.xcoff file to AppleguideGlueLib to link.                                    
  24.                  8/31/95    Yan        Moved to ShareWare
  25.  
  26.     To Do:
  27. */
  28.  
  29.  
  30.  
  31. #ifndef _AGSUPPORT_
  32. #include "AGSupprt.h"
  33. #endif
  34.  
  35. #ifndef _DLGDEFS_
  36. #include "DdgDefs.h"
  37. #endif
  38.  
  39. #ifndef _TEMPOBJ_
  40. #include "TempObj.h"
  41. #endif
  42.  
  43. #ifndef _USERSRCM_
  44. #include <UseRsrcM.h>
  45. #endif
  46.  
  47. #ifndef __CONTROLS__
  48. #include "Controls.h"
  49. #endif
  50.  
  51. #ifndef __ICONS__
  52. #include "Icons.h"
  53. #endif
  54.  
  55. #ifndef _INFODEFS_
  56. #include "InfoDefs.h"
  57. #endif
  58.  
  59. //#include "Utilities.h"
  60.  
  61. #if qDebug
  62. #include "TraceMonitor.h"
  63. #define kModuleChannel    'GUID'
  64. #endif
  65.  
  66. #include <AppleGuide.h>
  67. #include <Balloons.h>
  68.  
  69. #ifndef __GESTALT__
  70. #include <Gestalt.h>
  71. #endif
  72.  
  73. #include <Folders.h>
  74. #include <Files.h>
  75. #include <Menus.h>
  76. #include <TextUtils.h>
  77.  
  78.  
  79.  
  80. #if GENERATING68K
  81. #pragma segment AppleGuide
  82. #endif
  83.  
  84.  
  85. /*******************************************************************************
  86. **    Globals
  87. *******************************************************************************/
  88.  
  89. #if PRAGMA_ALIGN_SUPPORTED
  90. #pragma options align=mac68k
  91. #endif
  92.  
  93. // Runtime structure
  94. typedef struct
  95. {
  96.     FSSpec        spec;
  97.     AGRefNum    ref;
  98. } InstalledGuideRec;
  99.  
  100. typedef struct
  101. {
  102.     short                count;
  103.     InstalledGuideRec    guide[1];
  104. } InstalledGuideList, **InstalledGuideListHdl;
  105.  
  106.  
  107. // Resources
  108. typedef struct {
  109.     Str32    name;
  110.     char    filler;
  111.     Str255    itemTitle;
  112. } GuideEntry;
  113.  
  114.  
  115. typedef struct {
  116.     short        count;
  117.     GuideEntry    guide[1];
  118. } GuideList, **GuideListHdl;
  119.  
  120.  
  121.  
  122. #if PRAGMA_ALIGN_SUPPORTED
  123. #pragma options align=reset
  124. #endif
  125.  
  126.  
  127. InstalledGuideListHdl    gInstalledGuidesList        = NULL;
  128. short                    gInstalledGuidesListSize    = 0;
  129. short                    gFirstAppleGuideItem        = 0;
  130. Boolean                    gAGInstallAttempted            = false;
  131. Boolean                    gAGInstallSucceeded            = false;
  132. FSSpec                    gFileSpec                    = { 0, 0, "\p" };
  133. unsigned long            gRefNum                        = 0;
  134.  
  135. // forward decl's
  136. static Boolean FindAppleGuideFolder( short *vol, long *dir );
  137. static void Plot( ControlHandle ctrlH, IconTransformType trans );
  138. static void InstallAppleGuide();
  139.  
  140. /*******************************************************************************
  141. **    Boolean IsAppleGuidePresent
  142. *******************************************************************************/
  143.  
  144. #ifdef _APPLEGUIDE_READY_
  145. Boolean IsAppleGuidePresent()
  146. {
  147.     // no point in using Gestalt any longer on PPC.  It can only tell whether the
  148.     // shared library was in the Extensions folder at boot time, not whether
  149.     // it's been removed or added since - which is what really determines
  150.     // whether we'll crash trying to call it.  (On 68K with Gestalt, though you
  151.     // get a "false positive" in the case where the user's removed the library
  152.     // from his extensions folder since boot, the AppleGuide code handles that
  153.     // very nicely with an error message rather than crashing.)
  154.  
  155. #if GENERATING68K
  156.     long    result = 0;
  157.     OSErr    err;
  158.     err = Gestalt(gestaltHelpMgrAttr, &result);
  159.     
  160.     Boolean present = ( err == noErr &&
  161.             (result & (1 << gestaltAppleGuidePresent)) != 0 );
  162. #elif GENERATINGPOWERPC
  163.     Boolean present = &AGOpenWithSequence != NULL;
  164. #endif
  165.     return present;
  166. }
  167. #endif
  168.  
  169.  
  170. /*******************************************************************************
  171. **    Boolean IsAppleGuideInstalled
  172. *******************************************************************************/
  173.  
  174. #if 0
  175. // not being used right now.
  176. /*
  177. Boolean IsAppleGuideInstalled()
  178. {
  179.     
  180.     return IsAppleGuidePresent() && gInstalledGuidesListSize != 0;
  181. }
  182. */
  183. #endif
  184.  
  185. /*******************************************************************************
  186. **    void InstallGuide
  187. *******************************************************************************/
  188.  
  189. static Boolean FindAppleGuideFolder( short *vol, long *dir )
  190. {
  191.     WASSERT( IsAppleGuidePresent() );
  192.     Boolean result = false;
  193.     CInfoPBRec        pb;
  194.     memset (&pb,0,sizeof(pb));
  195.  
  196.         //First find Extensions Folder
  197.     OSErr err = FindFolder( kOnSystemDisk, kExtensionFolderType,
  198.             kDontCreateFolder, &pb.dirInfo.ioVRefNum, &pb.dirInfo.ioDrDirID );
  199.     if ( err == noErr )
  200.     {
  201.         // Then find global guide folder within in.  Name stored in
  202.         // resource for localizability.
  203.         Str255 folderName;
  204.         // this can throw, but that should only be possible when a resource
  205.         // is missing (or low mem, I suppose, but would hope our preflight
  206.         // leaves enough room.)  Thus I'm going to let the error cascade
  207.         // on up.
  208.         ODGetIndString( folderName, kODShellGuideFilenameStrings,
  209.                 kODShellGuideFolderNameIndex );
  210.  
  211.         pb.dirInfo.ioNamePtr = folderName;
  212.         pb.dirInfo.ioFDirIndex = 0;
  213.         err = PBGetCatInfoSync( &pb );
  214.         if ( err == noErr )
  215.         {
  216.             *vol = pb.dirInfo.ioVRefNum;
  217.             *dir = pb.dirInfo.ioDrDirID;
  218.             result = true;
  219.         }
  220.     }
  221.     return result;
  222. }
  223.  
  224. #ifdef _APPLEGUIDE_READY_
  225. static void InstallAppleGuide()
  226. {
  227.     if ( !gAGInstallAttempted && IsAppleGuidePresent() )
  228.     {
  229.         gAGInstallAttempted = kODTrue;        // only try once -- so we aren't always failing
  230.  
  231.         short vol;
  232.         long dir;
  233.         if ( FindAppleGuideFolder( &vol, &dir ) )
  234.         {
  235.             // Just saving a reference (FSSpec) to the shell guide file
  236.             // -- whose name is in a resource.  AppleGuide itself should
  237.             // take care of the other files.  Devon says it should take
  238.             // care of the Shell Guide file too (so that I don't have to
  239.             // pass in the FSSpec) but that doesn't work.
  240.  
  241.             Str255 guideFileName;
  242.             ODGetIndString( guideFileName, kODShellGuideFilenameStrings,
  243.                     kODShellGuideFileNameIndex );
  244.  
  245.             OSErr err = FSMakeFSSpec( vol, dir, guideFileName, &gFileSpec );
  246.             // enable the dialog help buttons only if the Shell Guide file was
  247.             // found.  Other files (e.g. those provided by part developers) will
  248.             // still be available through the help menu, but not this way.  Since
  249.             // users expect to find help *about* the dialogs through those buttons
  250.             // and that help is not available, I think this makes the most sense.
  251.             gAGInstallSucceeded = err == noErr;
  252.         }
  253.     }
  254.     #if qDebug
  255.     else
  256.     {
  257.         Trace(kModuleChannel, kFatalMessageLevel, "•• AppleGuide not installed\n");
  258.     }
  259.     #endif
  260. }
  261. #endif
  262.  
  263.  
  264.  
  265. /*******************************************************************************
  266. **    void CloseAppleGuide
  267. *******************************************************************************/
  268.  
  269. #ifdef _APPLEGUIDE_READY_
  270. void CloseAppleGuide()
  271. {
  272.     if ( IsAppleGuidePresent() )
  273.     {
  274.         short i;
  275.         
  276.         for ( i = 0; i < gInstalledGuidesListSize; i++ )
  277.         {
  278.             AGRefNum ref = (**gInstalledGuidesList).guide[i].ref;
  279.             
  280.             if ( ref != 0 && AGIsDatabaseOpen(ref) == true )
  281.             {
  282.                 // Guide already open
  283.                 AGClose(&ref);
  284.                 (**gInstalledGuidesList).guide[i].ref = 0;
  285.             }
  286.         }
  287.         
  288.         if ( gInstalledGuidesList ) 
  289.         {
  290.             DisposeHandle((Handle)gInstalledGuidesList);
  291.             gInstalledGuidesList = NULL;
  292.         }
  293.         AGQuit();
  294.     }
  295.     #if qDebug
  296.     else
  297.     {
  298.         Trace(kModuleChannel, kFatalMessageLevel, "•• AppleGuide not installed\n");
  299.     }
  300.     #endif
  301. }
  302. #endif
  303.  
  304.  
  305.  
  306. /*******************************************************************************
  307. **    Boolean OpenThisGuide
  308. *******************************************************************************/
  309.  
  310. #ifdef _APPLEGUIDE_READY_
  311. static Boolean OpenThisGuide(FSSpec* guide, AGRefNum* refNum,
  312. //        StringPtr keyword = NULL)
  313.         short sequenceID = 0 )
  314. {
  315.     WASSERT( IsAppleGuidePresent() );
  316.     Boolean guideOpened = false;
  317.     
  318.     if ( IsAppleGuidePresent() )
  319.     {
  320.         if ( AGIsDatabaseOpen(*refNum) == true )
  321.         {
  322.             // Guide already open
  323.             AGClose(refNum);
  324.             *refNum = 0;
  325.         }
  326.         
  327.         #if qDebug
  328.         Trace(kModuleChannel, kFatalMessageLevel,
  329.                 "•• Looking for keyword '%*.*s'\n", keyword[0], keyword[0],
  330.                 keyword+1);
  331.         #endif
  332.         
  333.         // Open AppleGuide
  334.         if ( guide == NULL || guide->name[0] != 0 )
  335.         {
  336.             AGErr        err;
  337.                         
  338.             // Open AppleGuide
  339. //            if ( keyword != NULL && keyword[0] != 0 )
  340.             if ( sequenceID != 0 )
  341.             {
  342.                 // Open using the specified keyword
  343. #if 0
  344.                 err = AGOpenWithSearch( guide, 0, NULL, keyword, refNum);
  345. #else
  346.                 err = AGOpenWithSequence( guide, 0, NULL, sequenceID, refNum );
  347. #endif
  348.             }
  349.             else
  350.             {
  351.                 // Open root window
  352.                 DebugStr( "\pcalling AGOpenWithView" );
  353.                 err = AGOpenWithView( guide, 0, NULL, kAGViewFullHowdy, refNum);
  354.             }
  355.             
  356.             if ( err == noErr )
  357.             {
  358.                 guideOpened = true;
  359.             }
  360.             #if qDebug
  361.             else
  362.             {
  363.                 Trace(kModuleChannel, kFatalMessageLevel, "••• AppleGuide opening error %d\n", err);
  364.             }
  365.             #endif
  366.         }
  367.         #if qDebug
  368.         else
  369.         {
  370.             Trace(kModuleChannel, kFatalMessageLevel, "•• No guide spec!\n");
  371.         }
  372.         #endif
  373.     }
  374.     #if qDebug
  375.     else
  376.     {
  377.         Trace(kModuleChannel, kFatalMessageLevel, "•• AppleGuide not installed\n");
  378.     }
  379.     #endif
  380.  
  381.     return guideOpened;
  382. }
  383. #endif
  384.  
  385. /*******************************************************************************
  386. **    Boolean OpenAppleGuide
  387. *******************************************************************************/
  388.  
  389. #ifdef _APPLEGUIDE_READY_
  390. //Boolean OpenAppleGuide(StringPtr keyword)
  391. Boolean OpenAppleGuide( short sequenceID )
  392. {
  393.     WASSERT( IsAppleGuidePresent() );
  394.     Boolean opened = false;
  395.  
  396.     if ( true || (gInstalledGuidesListSize > 0) )//|| (gFileSpec.name[0] != 0) )
  397.     {
  398.         TempODHandleLock    list((Handle)gInstalledGuidesList);
  399.         
  400.         
  401. //        opened = OpenThisGuide( kAGDefault, &gRefNum, keyword );
  402. //        opened = OpenThisGuide( &gFileSpec, &gRefNum, keyword );
  403.         opened = OpenThisGuide( &gFileSpec, &gRefNum, sequenceID );
  404.  
  405. //        opened =  OpenThisGuide( &(**gInstalledGuidesList).guide[0].spec,
  406. //                &(**gInstalledGuidesList).guide[0].ref, keyword);
  407.     }
  408.     return opened;
  409. }
  410. #endif
  411.  
  412. /*******************************************************************************
  413. **    InitAppleGuideSupport
  414. *******************************************************************************/
  415. //short gAGButtonItem = -1;
  416. ControlDefUPP gCtrlDefUPP = NULL;
  417. Handle ctrlDefStub = NULL;
  418. Handle gIconSuite = NULL;
  419.  
  420. const short kControlInactive = 255;
  421. const short kControlActive = 0;
  422. const short kCDEFAddrOffset = 8;
  423.  
  424. pascal long AGBUTTONCDEF( short code, ControlHandle ctrlH,
  425.         short message, long param );
  426.  
  427. #ifdef _APPLEGUIDE_READY_
  428. void InitAppleGuideSupport()
  429. {
  430.     CUsingLibraryResources r;
  431.     InstallAppleGuide();        // returns immediately if installed
  432.     
  433.     // Must fix up the CDEF resource whether the install succeeded
  434.     // or not; else we'll jsr to 0.
  435.     if ( !gCtrlDefUPP )
  436.     {
  437.         gCtrlDefUPP = NewControlDefProc( AGBUTTONCDEF );
  438.         ctrlDefStub = Get1Resource( 'CDEF', kAGButtonCDEFId);
  439.         WASSERT( ctrlDefStub != NULL );
  440.         (*(ControlDefUPP*)&((*ctrlDefStub)[kCDEFAddrOffset])) = gCtrlDefUPP;
  441.     }
  442. }
  443. #endif
  444.  
  445. /*******************************************************************************
  446. **    ODGetIndShort
  447.     A utility function patterned after ODGetIndString that might well belong
  448.     elsewhere.  Note that it assumes a resource of type 'int#', which follows
  449.     'STR#' in being a 1-based array of shorts whose first short gives the length
  450.     of the array.
  451. *******************************************************************************/
  452.  
  453. short ODGetIndShort( short id, short index )
  454. {
  455.     // I expect this not to get called, as the control won't generate hits
  456.     // in the dialogs.
  457.     WASSERT( IsAppleGuidePresent() );
  458.  
  459.     short result = 0;
  460.     ODSLong savedRef = BeginUsingLibraryResources();
  461.     Handle h = Get1Resource( 'int#', id );
  462.     OSErr err = ResError();
  463.     if( h ) {
  464. #if ODDebug
  465.         if( index<1 || index>**(short**)h ) {
  466.             WARN("ODGetIndString(%hd,%hd): invalid index",id,index);
  467.             err= kODErrValueOutOfRange;
  468.         } else
  469. #endif
  470.         result = ((short*)*h)[index];        // that it's 1-based makes skipping
  471.                                             // the count easy
  472.         ReleaseResource(h);
  473.     }
  474.     EndUsingLibraryResources(savedRef);
  475.     if( err ) {
  476.         THROW(err);
  477.         THROW(resNotFound);
  478.     }
  479.     return result;
  480. }
  481.  
  482. /*******************************************************************************
  483. **    TakedownAppleGuideSupport
  484. *******************************************************************************/
  485.  
  486. #ifdef _APPLEGUIDE_READY_
  487. void TakedownAppleGuideSupport()
  488. {
  489.     if ( gCtrlDefUPP )
  490.     {
  491.         DisposeRoutineDescriptor( gCtrlDefUPP );
  492.         gCtrlDefUPP = NULL;
  493.     }
  494.     if ( ctrlDefStub )
  495.     {
  496.         CUsingLibraryResources r;    // <eeh> find out if necessary
  497.         ReleaseResource( ctrlDefStub );
  498.         ctrlDefStub = NULL;
  499.     }
  500.     if ( gIconSuite )
  501.     {
  502.         DisposeIconSuite( gIconSuite, true );
  503.         gIconSuite = NULL;
  504.     }
  505.     CloseAppleGuide();
  506. }
  507. #endif
  508.  
  509. /*******************************************************************************
  510. **    DialogSetUpAppleGuide
  511. *******************************************************************************/
  512.  
  513. #ifdef _APPLEGUIDE_READY_
  514. void DialogSetUpAppleGuide( DialogPtr dlg, short item )
  515. {
  516.     short             itemType;
  517.     ControlHandle    cntrlHandle;
  518.     Rect scratchRect;
  519.     GetDialogItem(dlg, item, &itemType, (Handle*)&cntrlHandle,
  520.             &scratchRect );
  521.  
  522.     HiliteControl( cntrlHandle,
  523.             gAGInstallSucceeded ? kControlActive : kControlInactive);
  524.  
  525.     if ( gIconSuite == NULL )
  526.     {
  527.         CUsingLibraryResources r;
  528.         short iconsID = (*cntrlHandle)->contrlRfCon;
  529.         // ignore error; gIconSuite *should* remain null.
  530.         OSErr err = GetIconSuite( &gIconSuite, iconsID,
  531.             kSelectorAllSmallData );
  532.         if ( err != noErr )
  533.         {
  534.             gIconSuite = NULL;
  535.             WARN( "GetIconSuite returned null" );
  536.         }
  537.     }
  538. }
  539. #endif
  540.  
  541. /*******************************************************************************
  542. **    Plot
  543. *******************************************************************************/
  544.  
  545. IconTransformType gCurrentTransform = kTransformNone;
  546.  
  547. static void Plot( ControlHandle ctrlH, IconTransformType trans )
  548. {
  549.     if ( gIconSuite )
  550.     {
  551.         OSErr err = PlotIconSuite( &(*ctrlH)->contrlRect,
  552.                 kAlignNone, gCurrentTransform=trans,
  553.                 (Handle)gIconSuite );
  554.         WASSERT( err == noErr );
  555.     }
  556. }
  557.  
  558. /*******************************************************************************
  559. **    AGBUTTONCDEF
  560. *******************************************************************************/
  561.  
  562. pascal long AGBUTTONCDEF( short code, ControlHandle ctrlH,
  563.         short message, long param )
  564. {
  565.     long result = 0;
  566.     switch ( message )
  567.     {
  568.         case drawCntl:
  569.             if ( (*ctrlH)->contrlVis /* == 255 visible */ )
  570.             {
  571.                 short activeCode = (*ctrlH)->contrlHilite;
  572.                 switch ( activeCode )
  573.                 {
  574.                     case kControlInactivePart:
  575.                         Plot( ctrlH, kTransformDisabled );
  576.                         break;
  577.                     case kControlButtonPart:
  578.                         WASSERT( IsAppleGuidePresent() );
  579.                         Plot( ctrlH, kTransformSelected );
  580.                         break;
  581.                     default:
  582.                         Plot( ctrlH, kTransformNone );
  583.                 }
  584.             }
  585.             break;
  586.         case testCntl:
  587.             WASSERT( IsAppleGuidePresent() );
  588.             Point pt = *(Point*)¶m;
  589.             if ( PtInRect( pt, &(*ctrlH)->contrlRect ) )
  590.             {
  591.                 result = kControlButtonPart;
  592.                 if ( gCurrentTransform == kTransformNone )
  593.                     Plot( ctrlH, kTransformSelected );
  594.             }
  595.             break;
  596.  
  597.         // we could use these rather than the methods above to do ifam init
  598. //        case initCntl:
  599. //        case dispCntl:
  600. //            break;
  601.  
  602.         // case calcCRgns:    // not an issue for OpenDoc
  603.         case calcCntlRgn:
  604.             param &= 0x7fffffff;        // clear high bit (NIM 5-112)
  605.             RectRgn( (RgnHandle)param, &(*ctrlH)->contrlRect );
  606.             break;
  607.         
  608.     }
  609.     return result;
  610. }
  611.